Fix lost pivots in probabilistic linear algebra - #370
Merged
mohabsafey merged 3 commits intoOct 2, 2026
Merged
Conversation
The random multipliers of the probabilistic linear algebra were drawn
as rand() & fc, i.e. masked with the field characteristic itself and not
reduced modulo it. For fc = 2^30+3 this only yields the values 0, 1, 2, 3,
2^30, ..., 2^30+3, so the multipliers lie in {0, +-1, +-2, +-3} mod fc,
and fc itself (which is 0 mod fc) passes the nonzero check. Rows were
then dropped from the random combinations, and since a block stops as soon
as one combination reduces to zero, pivots were lost on small matrices.
With -l 42 this gave wrong Groebner bases for about 40% of the seeds on
nonradical-radicalshape-31. Draw the multipliers as rand() % fc instead,
which is uniform in [1, fc-1] after rejecting 0; the 8- and 16-bit
variants had the same problem.
Add a regression test running -l 42 on 40 consecutive seeds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The array of random multipliers is indexed with rpb entries per thread, but it was allocated with ncols entries per thread. When a block has more rows than the matrix has columns, which happens for small matrices, this wrote past the end of the array. Allocate rpb entries per thread as in the 8- and 16-bit versions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The parallel loop iterates over the blocks of rows but ran up to the number of rows ntr instead of the number of blocks nb. The additional iterations have no rows to handle, so this only removes useless work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wegank
force-pushed
the
fix-prob-la-multipliers
branch
from
October 1, 2026 08:30
55a3511 to
8658e15
Compare
wegank
marked this pull request as ready for review
October 1, 2026 09:26
ederc
approved these changes
Oct 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With the probabilistic sparse/dense linear algebra (
-l 42), msolve fails oninput_files/nonradical-radicalshape-31.msfor many random seeds, e.g.The output file
outis empty, yet msolve exits with status 0. On macOS, 16 of seeds 1..40 fail at-t 1.-l 2and-l 44always succeed.The cause is in the linear algebra. It loses pivots, so F4 computes a wrong Gröbner basis. With
-v 2, the F4 run after adding the linear form shows a single round6 x 6 ... 1 new 2 zero. This basis gives a larger degree (4 instead of 3) than the run before the linear form was added. msolve detects this inconsistency and writes no result.Root cause
The random multipliers of the probabilistic linear algebra were drawn as
This masks with the field characteristic itself instead of reducing modulo it. For
fc = 1073741827 = 2^30 + 3(binary1000...0011) the only possible values are 0, 1, 2, 3, 2^30, 2^30+1, 2^30+2, 2^30+3. As a result:2^30 + 3 = fcis 0 mod p but passes the!= 0check, so about one draw in seven drops a row from the random combination.A block stops as soon as one random combination reduces to zero, so pivots were lost, especially on small matrices. The 8- and 16-bit versions have the same problem.
Changes
rand() % fc. Once the existing loop rejects 0, they are uniform in [1, fc-1].probabilistic_sparse_dense_echelon_form_ff_32: the multiplier array is indexed withrpbentries per thread but was allocated withncolsentries per thread. When a block has more rows than the matrix has columns, this wrote past the end of the array. It is now allocated withrpbentries per thread, as in the 8- and 16-bit versions.probabilistic_dense_linear_algebra_ff_{8,16,32}: the parallel loop ran up to the number of rowsntrinstead of the number of blocksnb. The extra iterations had no rows to handle, so this only removes wasted work.Tests
test/diff/diff_bug-prob-sparse-dense-la.sh: runs-l 42onnonradical-radicalshape-31for 40 consecutive seeds with-t 1and-t 2, and compares the results withoutput_files/nonradical-radicalshape-31.res. Line 5 (the random linear form, which depends on the seed) is not compared. Because it uses many seeds, the test catches the bug whatever the platform'srand(). It fails onmasterand passes with this PR.-l 2for primes 1073741827, 65521 and 251, with-t 1,-t 2and-t 4, for seeds 1..200.make checkpasses after each commit.With this PR, the example above succeeds for all seeds: msolve writes the correct result to
outand exits with status 0.Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
Exiting with status 0 after a failed computation is a separate problem, and it is not specific to this bug. In positive characteristic, msolve does not report failures it detects, whatever their cause. Such failures can still occur after this PR: probabilistic linear algebra can still be unlucky, with a probability of about 1/p per block, and some inputs fail without genericity handling (
-c 0). #371 will handle this: when msolve detects a wrong dimension or degree, it restarts the computation, and any other failure makes msolve exit with status 1.